package com.sita.cfmoto.version;

import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.NotificationCompat;

import com.sita.cfmoto.R;
import com.sita.cfmoto.support.GlobalContext;
import com.sita.cfmoto.utils.L;
import com.sita.cfmoto.version.rest.VersionCheckHelper;
import com.sita.cfmoto.version.rest.VersionModule;

import java.util.List;

public class UpdateChecker extends Fragment {

    //private static final String NOTIFICATION_ICON_RES_ID_KEY = "resId";
    private static final String NOTICE_TYPE_KEY = "type";

    private int noticeStyle;
    private static final String TAG = "UpdateChecker";

    private FragmentActivity mContext;
    private int mTypeOfNotice;

    /**
     * Show a Dialog if an update is available for download. Callable in a
     * FragmentActivity. Number of checks after the dialog will be shown:
     * default, 5
     *
     * @param fragmentActivity Required.
     */
    public static void checkUpdate(FragmentActivity fragmentActivity, int style) {
        FragmentTransaction content = fragmentActivity.getSupportFragmentManager().beginTransaction();
        UpdateChecker updateChecker = new UpdateChecker();
        Bundle args = new Bundle();
        args.putInt(NOTICE_TYPE_KEY, style);
        //args.putInt(SUCCESSFUL_CHECKS_REQUIRED_KEY, 5);
        updateChecker.setArguments(args);
        content.add(updateChecker, "UpdateChecker").commit();
    }


    /**
     * Show a Notification if an update is available for download. Callable in a
     * FragmentActivity Specify the number of checks after the notification will
     * be shown.
     *
     * @param fragmentActivity Required.
     */
//    public static void checkForNotification(FragmentActivity fragmentActivity, String url) {
//        FragmentTransaction content = fragmentActivity.getSupportFragmentManager().beginTransaction();
//        UpdateChecker updateChecker = new UpdateChecker();
//        Bundle args = new Bundle();
//        args.putInt(NOTICE_TYPE_KEY, NOTICE_NOTIFICATION);
//        //args.putInt(NOTIFICATION_ICON_RES_ID_KEY, notificationIconResId);
//        //args.putInt(SUCCESSFUL_CHECKS_REQUIRED_KEY, 5);
//        updateChecker.setArguments(args);
//        content.add(updateChecker, Constants.CHECK_DIALOG_TAG).commit();
//    }


    /**
     * This class is a Fragment. Check for the method you have chosen.
     */
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        mContext = (FragmentActivity) activity;
        Bundle args = getArguments();
        mTypeOfNotice = args.getInt(NOTICE_TYPE_KEY);
        //mSuccessfulChecksRequired = args.getInt(SUCCESSFUL_CHECKS_REQUIRED_KEY);
        //mNotificationIconResId = args.getInt(NOTIFICATION_ICON_RES_ID_KEY);
        checkForUpdates();
    }

    /**
     * Heart of the library. Check if an update is available for download
     * parsing the desktop Play Store page of the app
     */
    private void checkForUpdates() {
        VersionCheckHelper.INSTANCE.checkNewVersion(new CheckUpdateListener() {
            @Override
            public void onSuccess(VersionModule vm) {
                if (vm != null) {
                    int versionCode = vm.getVersionCode();
                    String versionName = vm.getVersionName();
                    final String apkUrl = vm.getUrl();
                    String description = null;

                    List<String> desc = vm.getDescription();
                    if (desc != null && !desc.isEmpty()) {
                        StringBuilder b = new StringBuilder();
                        int size = desc.size();
                        for (int i = 0; i < size; i++) {
                            b.append(desc.get(i));
                            if (i < size - 1) {
                                b.append("\n");
                            }
                        }
                        description = b.toString();
                    }
                    try {
                        int apkCode = mContext.getPackageManager().getPackageInfo(GlobalContext
                                .getGlobalContext().getPackageName(), 0).versionCode;
                        if (versionCode > apkCode) {
                            if (mTypeOfNotice == UpdateNoticeStyle.NOTIFICATION) {
                                showNotification(versionName, description, apkUrl);
                            } else if (mTypeOfNotice == UpdateNoticeStyle.DIALOG) {
                                showDialog(versionName, description, apkUrl);
                            } else if (mTypeOfNotice == UpdateNoticeStyle.DIALOG_NOTIFICATION) {
                                showDialog(versionName, description, apkUrl);
                                showNotification(versionName, description, apkUrl);
                            }
                        } else {
                            //Toast.makeText(mContext, mContext.getString(R.string.app_no_new_update), Toast.LENGTH_SHORT).show();
                        }
                    } catch (PackageManager.NameNotFoundException e) {
                        L.e("checkForUpdates()", e);
                    }
                }
            }

            @Override
            public void onFail(Throwable throwable) {

            }
        });
    }

    /**
     * Show dialog
     */
    public void showDialog(String versionName, String content, String apkUrl) {
        UpdateDialog d;
        d = (UpdateDialog) mContext.getSupportFragmentManager().findFragmentByTag(Constants.CHECK_DIALOG_TAG);
        if (d == null || !d.isVisible()){
            d = new UpdateDialog();
        }
        Bundle args = new Bundle();
        args.putString(Constants.APK_VERSION_NAME, versionName);
        args.putString(Constants.APK_UPDATE_CONTENT, content);
        args.putString(Constants.APK_DOWNLOAD_URL, apkUrl);
        d.setArguments(args);

        d.show(mContext.getSupportFragmentManager(), Constants.CHECK_DIALOG_TAG);
    }

    /**
     * Show Notification
     */
    public void showNotification(String versionName, String content, String apkUrl) {
        String title = String.format(getString(R.string.newUpdateAvailable), versionName);
        android.app.Notification noti;
//        Intent myIntent = new Intent(mContext, DownloadService.class);
//        myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        myIntent.putExtra(Constants.APK_DOWNLOAD_URL, apkUrl);
//        PendingIntent pendingIntent = PendingIntent.getService(mContext, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(apkUrl));
        myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        int smallIcon = mContext.getApplicationInfo().icon;
        noti = new NotificationCompat.Builder(mContext).setTicker(title)
                .setContentTitle(title).setContentText(content).setSmallIcon(smallIcon)
                .setContentIntent(pendingIntent).build();

        noti.flags = android.app.Notification.FLAG_AUTO_CANCEL;
        NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(Constants.UPDATE_NOTIFICATION_ID, noti);
    }

    /**
     * Check if a network available
     */
    public static boolean isNetworkAvailable(Context context) {
        boolean connected = false;
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (cm != null) {
            NetworkInfo ni = cm.getActiveNetworkInfo();
            if (ni != null) {
                connected = ni.isConnected();
            }
        }
        return connected;
    }


}